//
//  SacredWords_AppDelegate.m
//  SacredWords
//
//  Created by Orbitus on 8/26/07.
//  Copyright __MyCompanyName__ 2007 . All rights reserved.
//

#import "SacredWords_AppDelegate.h"

@implementation SacredWords_AppDelegate

- (void)awakeFromNib
{
	[mySystemMessages setStringValue:@"Welcome, Ready to process!"];
	[myDNAView setMOC:[self managedObjectContext] MOM:[self managedObjectModel]];
	myBundle	= [NSBundle mainBundle];
	myAppPath	= [myBundle bundlePath];
	myAppFolderPath	= [myAppPath stringByDeletingLastPathComponent];
	myDataFolderPath	= [myAppFolderPath stringByAppendingPathComponent: @"data"];
	
	[cddPathControl setStringValue: [myDataFolderPath stringByAppendingPathComponent:@"test.cdd" ]];
	[ucePathControl setStringValue: [myDataFolderPath stringByAppendingPathComponent:@"test.uce" ]];
	[blocksPathControl setStringValue: [myDataFolderPath stringByAppendingPathComponent:@"test.blocks" ]];
	[ncuPathControl setStringValue: [myDataFolderPath stringByAppendingPathComponent:@"test.fasta" ]];
	
	entities = [managedObjectModel entitiesByName];
	
	uceEntity = [entities valueForKey:@"UCE"];
	ncuEntity = [entities valueForKey:@"NeurosporaCrassaUniqueIdentifier"];
	cddEntity = [entities valueForKey:@"ConservedProteinDomainDatabase"];
	blocksEntity = [entities valueForKey:@"Blocks"];
	clusterEntity = [entities valueForKey:@"Cluster"];
	
	
	
	ncuSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
	ncuSortDescriptors = [NSArray arrayWithObject: ncuSort];
	ncuFetch = [[NSFetchRequest alloc] init];
	[ncuFetch setEntity: ncuEntity];
	[ncuFetch setSortDescriptors: ncuSortDescriptors];
	
	cddSort = [[NSSortDescriptor alloc] initWithKey:@"ncuID" ascending:YES];
	cddSortDescriptors = [NSArray arrayWithObject: cddSort];
	cddFetch = [[NSFetchRequest alloc] init];
	[cddFetch setEntity: cddEntity];
	[cddFetch setSortDescriptors: cddSortDescriptors];
	
	uceSort = [[NSSortDescriptor alloc] initWithKey:@"ncuID" ascending:YES];
	uceSortDescriptors = [NSArray arrayWithObject: uceSort];
	uceFetch = [[NSFetchRequest alloc] init];
	[uceFetch setEntity: uceEntity];
	[uceFetch setSortDescriptors: uceSortDescriptors];
	
	blocksSort = [[NSSortDescriptor alloc] initWithKey:@"ncuID" ascending:YES];
	blocksSortDescriptors = [NSArray arrayWithObject: blocksSort];
	blocksFetch = [[NSFetchRequest alloc] init];
	[blocksFetch setEntity: blocksEntity];
	[blocksFetch setSortDescriptors: blocksSortDescriptors];
	
	clusterSort = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:YES];
	clusterSortDescriptors = [NSArray arrayWithObject: clusterSort];
	clusterFetch = [[NSFetchRequest alloc] init];
	[clusterFetch setEntity: clusterEntity];
	[clusterFetch setSortDescriptors: clusterSortDescriptors];
	
}
/**
 Returns the support folder for the application, used to store the Core Data
 store file.  This code uses a folder named "SacredWords" for
 the content, either in the NSApplicationSupportDirectory location or (if the
 former cannot be found), the system's temporary directory.
 */

- (NSString *)applicationSupportFolder {
	
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
    return [basePath stringByAppendingPathComponent:@"SacredWords"];
}


/**
 Creates, retains, and returns the managed object model for the application 
 by merging all of the models found in the application bundle.
 */

- (NSManagedObjectModel *)managedObjectModel {
	
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
	
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}


/**
 Returns the persistent store coordinator for the application.  This 
 implementation will create and return a coordinator, having added the 
 store for the application to it.  (The folder for the store is created, 
 if necessary.)
 */

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator {
	
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
	
    NSFileManager *fileManager;
    NSString *applicationSupportFolder = nil;
    NSURL *url;
    NSError *error;
    
    fileManager = [NSFileManager defaultManager];
    applicationSupportFolder = [self applicationSupportFolder];
    if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
        [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
    }
    id tempDataFolder = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"data/SacredWords.sql"];
    url = [NSURL fileURLWithPath: tempDataFolder];
	//    url = [NSURL fileURLWithPath: [myDataFolderPath stringByAppendingPathComponent: @"SacredWords.sql"]];
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]){
        [[NSApplication sharedApplication] presentError:error];
    }    
	
    return persistentStoreCoordinator;
}


/**
 Returns the managed object context for the application (which is already
 bound to the persistent store coordinator for the application.) 
 */

- (NSManagedObjectContext *) managedObjectContext {
	
    if (managedObjectContext != nil) {
        return managedObjectContext;
    }
	
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    
    return managedObjectContext;
}


/**
 Returns the NSUndoManager for the application.  In this case, the manager
 returned is that of the managed object context for the application.
 */

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
    return [[self managedObjectContext] undoManager];
}


/**
 Performs the save action for the application, which is to send the save:
 message to the application's managed object context.  Any encountered errors
 are presented to the user.
 */

- (IBAction) saveAction:(id)sender {
	
    NSError *error = nil;
    if (![[self managedObjectContext] save:&error]) {
        [[NSApplication sharedApplication] presentError:error];
    }
}

- (IBAction)importAllData:sender
{
	
	[mySystemMessages setStringValue:@"Starting Import"];
	[myIndicator startAnimation:self];
	int i;
	NSScanner *theScanner;
	NSString *line,*sequenceString;
	NSMutableArray *ncuLines;
	NSMutableArray *blocksLines;
	NSMutableArray *cddLines;
	NSMutableArray *uceLines;
	char string [200];
	sequenceString  = @"";
	
	sequenceString = [[NSString alloc] init]; 					
	ncuLines = [[NSMutableArray alloc] init];					
	blocksLines = [[NSMutableArray alloc] init];					
	cddLines = [[NSMutableArray alloc] init];					
	uceLines = [[NSMutableArray alloc] init];					
	
	id ncuPath = [ncuPathControl stringValue];
	id cddPath = [cddPathControl stringValue];
	id ucePath = [ucePathControl stringValue];
	id blocksPath = [blocksPathControl stringValue];
	
	/*id ncuPath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"data"] stringByAppendingPathComponent:@"test.fasta"];
	 id cddPath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"data"] stringByAppendingPathComponent:@"test.cdd"];
	 id ucePath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"data"] stringByAppendingPathComponent:@"test.uce"];
	 id blocksPath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"data"] stringByAppendingPathComponent:@"test.blocks"];
	 */
	FILE * ncu		= fopen([ncuPath UTF8String],"r") ;
	FILE * blocks	= fopen([blocksPath UTF8String],"r") ;
	FILE * cdd		= fopen([cddPath UTF8String],"r") ;
	FILE * uce		= fopen([ucePath UTF8String],"r") ;
	
	id tabSet = [NSCharacterSet characterSetWithCharactersInString:@"\t"];
	NSLog(@" 216");
	//NCU FILE FIRST
	if (ncu == NULL) {
		fprintf(stderr,"***  Unable to open NCU file, returning NULL! *** \n");
	} else {
		char *sa;
		sa 	= fgets (string, 200, ncu);
		while( sa!= NULL)
		{
			[ncuLines addObject: [[NSString alloc] initWithUTF8String:sa]];			
			sa 	= fgets (string, 200, ncu);
		}
		fclose(ncu);
	}
	if (cdd == NULL) {
		fprintf(stderr,"***  Unable to open CDD file, returning NULL! *** \n");
	} else {
		char *sa;
		sa 	= fgets (string, 200, cdd);
		while( sa!= NULL)
		{
			[cddLines addObject: [[NSString alloc] initWithUTF8String:sa]];			
			sa 	= fgets (string, 200, cdd);
		}
		fclose(cdd);
	}
	if (blocks == NULL) {
		fprintf(stderr,"***  Unable to open BLOCKS file, returning NULL! *** \n");
	} else {
		char *sa;
		sa 	= fgets (string, 200, blocks);
		while( sa!= NULL)
		{
			[blocksLines addObject: [[NSString alloc] initWithUTF8String:sa]];			
			sa 	= fgets (string, 200, blocks);
		}
		fclose(blocks);
	}
	if (uce == NULL) {
		fprintf(stderr,"***  Unable to open UCE file, returning NULL! *** \n");
	} else {
		char *sa;
		sa 	= fgets (string, 200, uce);
		while( sa!= NULL)
		{
			[uceLines addObject: [[NSString alloc] initWithUTF8String:sa]];			
			sa 	= fgets (string, 200, uce);
		}
		fclose(uce);
	}
	[mySystemMessages setStringValue:@"Done Reading... Processing Data..."];
	id newNCU;
	for ( i=0; i < [ncuLines count]; i++)
	{
		line = [ncuLines objectAtIndex:i];
		if ([line hasPrefix:@">"])  {
			newNCU = [NSEntityDescription insertNewObjectForEntityForName:@"NeurosporaCrassaUniqueIdentifier" inManagedObjectContext:managedObjectContext];
			[newNCU setValue:@"" forKey:@"proteinSequence"];
			[newNCU setValue:[line substringWithRange:NSMakeRange(1, 8)] forKey:@"name"];
		}
		else
		{
			[newNCU setValue:[[newNCU valueForKey:@"proteinSequence"] stringByAppendingString:[[line stringByReplacingOccurrencesOfString:@"\n" withString:@""] stringByReplacingOccurrencesOfString:@"*" withString:@"" ]] forKey:@"proteinSequence"];
			
		}
	}
	NSLog(@" 282");
	
	
	id newBlocks;
	NSString * proteinID = @"";
	NSString * blocksID = @"";
	int blocksProtStart;
	int blocksProtEnd;
	
	
	for ( i=1; i < [blocksLines count]; i++)
	{
		line = [blocksLines objectAtIndex:i];
		theScanner = [NSScanner scannerWithString:line];
		
		while ([theScanner isAtEnd] == NO) {
			if ([theScanner scanUpToCharactersFromSet:tabSet intoString:&proteinID] &&
				[theScanner scanUpToCharactersFromSet:tabSet intoString:&blocksID] &&
				[theScanner scanInt:&blocksProtStart] &&
				[theScanner scanInt:&blocksProtEnd] ) {
			}
		}
		
		
		newBlocks = [NSEntityDescription insertNewObjectForEntityForName:@"Blocks" inManagedObjectContext:managedObjectContext];
		[newBlocks setValue:proteinID forKey:@"ncuID"];
		[newBlocks setValue:[NSNumber numberWithInt: blocksProtEnd] forKey:@"protEnd"];
		[newBlocks setValue:[NSNumber numberWithInt: blocksProtStart] forKey:@"protStart"];
		[newBlocks setValue:blocksID forKey:@"blocksID"];
	}
	
	id newCDD;
	NSString * cddID = @"";
	proteinID = @"";
	int cddProtStart;
	int cddProtEnd;
	
	proteinID = @"";
	
	for ( i=1; i < [cddLines count]; i++)
	{
		line = [cddLines objectAtIndex:i];
		theScanner = [NSScanner scannerWithString:line];
		
		while ([theScanner isAtEnd] == NO) {
			if ([theScanner scanUpToCharactersFromSet:tabSet intoString:&proteinID] &&
				[theScanner scanUpToCharactersFromSet:tabSet intoString:&cddID] &&
				[theScanner scanInt:&cddProtStart] &&
				[theScanner scanInt:&cddProtEnd] ) {
				//				NSLog(@"%@,%@,%i,%i",[proteinID description],[cddID description],cddProtStart,cddProtEnd);
			}
		}
		
		
		newCDD = [NSEntityDescription insertNewObjectForEntityForName:@"ConservedProteinDomainDatabase" inManagedObjectContext:managedObjectContext];
		
		
		[newCDD setValue:proteinID forKey:@"ncuID"];
		[newCDD setValue:[NSNumber numberWithInt: cddProtEnd] forKey:@"protEnd"];
		[newCDD setValue:[NSNumber numberWithInt: cddProtStart] forKey:@"protStart"];
		[newCDD setValue:cddID forKey:@"cddID"];
	}
	
	id newUCE;
	NSString * uceSequence = @"";
	NSString * ucePeptide = @"";
	int uceProtStart;
	int uceProtEnd;
	int uceID;
	NSLog(@" 351");
	proteinID = @"";
	
	for ( i=1; i < [uceLines count]; i++)
	{
		line = [uceLines objectAtIndex:i];
		theScanner = [NSScanner scannerWithString:line];
		
		while ([theScanner isAtEnd] == NO) {
			if ([theScanner scanUpToCharactersFromSet:tabSet intoString:&proteinID] &&
				[theScanner scanInt:&uceProtStart] &&
				[theScanner scanInt:&uceProtEnd] &&
				[theScanner scanInt:&uceID] &&
				[theScanner scanUpToCharactersFromSet:tabSet intoString:&uceSequence] &&
				[theScanner scanUpToCharactersFromSet:tabSet intoString:&ucePeptide]	) {
				//NSLog(@"%@,%i,%i,%i,%@,%@",[proteinID description],uceID,uceProtStart,uceProtEnd,[uceSequence description],[ucePeptide description]);
			}
		}
		
		newUCE = [NSEntityDescription insertNewObjectForEntityForName:@"UCE" inManagedObjectContext:managedObjectContext];
		
		[newUCE setValue:proteinID forKey:@"ncuID"];
		[newUCE setValue:[NSNumber numberWithInt: uceProtEnd] forKey:@"protEnd"];
		[newUCE setValue:[NSNumber numberWithInt: uceProtStart] forKey:@"protStart"];
		[newUCE setValue:[NSNumber numberWithInt: uceID] forKey:@"uceID"];
		[newUCE setValue:uceSequence forKey:@"uceDNASequence"];
		[newUCE setValue:ucePeptide forKey:@"ucePeptideSequence"];
		//NSLog(@"%@",[newUCE description]);
	}
	
	NSLog(@" 380");
	[ncuFetch setPredicate:nil];
	
	NSArray * myNCU = [managedObjectContext executeFetchRequest:ncuFetch error:nil];
	
	int cddNum=0,uceNum=0,blocksNum=0;
	int j;
	
	//predicate = [NSPredicate predicateWithFormat:@"ncuID like[c] %@",[tempNCU name] ];
	
	[blocksFetch setPredicate:nil];
	[cddFetch setPredicate:nil];
	[uceFetch setPredicate:nil];
	
	int finBlock=0;
	int finCDD=0;
	int finUCE=0;
	//	NSLog(@"%@",[myUCE description]);		
	[mySystemMessages setStringValue:@"Creating Relationships..."];
	for (j=0; j<[myNCU count]; j++)
	{	
		
		id myBlocks = [managedObjectContext executeFetchRequest:blocksFetch error:nil];
		id myCDD = [managedObjectContext executeFetchRequest:cddFetch error:nil];
		id myUCE = [managedObjectContext executeFetchRequest:uceFetch error:nil];		
		
		id holder;
		id tempNCU = [myNCU objectAtIndex:j];
		//[mySystemMessages setStringValue:[[mySystemMessages stringValue] stringByAppendingString:[[myNCU objectAtIndex:j] valueForKey:@"ncuID"]]];
		NSLog(@" 400 loop");
		NSLog(@"%@",[[myNCU objectAtIndex:j]description]);		
		
		if ( finBlock == 0 ){
			
			
			if ( [[[myBlocks objectAtIndex:blocksNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])
			{
				while ([[[myBlocks objectAtIndex:blocksNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])
				{
					holder = [[myBlocks objectAtIndex:blocksNum] mutableSetValueForKey:@"ncus"];
					[holder addObject:tempNCU];
					[[myBlocks objectAtIndex:blocksNum] setValue:holder forKey:@"ncus"];
					
					holder = [tempNCU mutableSetValueForKey:@"blocks"];
					[holder addObject:[myBlocks objectAtIndex:blocksNum]];
					[tempNCU setValue:holder forKey:@"blocks"];
					
					[tempNCU setValue:[NSNumber numberWithInt:[[tempNCU valueForKey:@"blocksCount"] intValue] +1] forKey:@"blocksCount"];
					
					//if (blocksNum < [myBlocks count])
					blocksNum++;
					//NSLog(@"Blocks=%i,%i",blocksNum, [myBlocks count]);
					
					if (blocksNum == [myBlocks count])
					{
						finBlock = 1;
						break;
					}
				}
				
			}
		}
		
		if ( finCDD == 0 ) {
			
			
			if ( [[[myCDD objectAtIndex:cddNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])
			{
				while([[[myCDD objectAtIndex:cddNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])	
				{
					//	NSLog(@"CDDs");
					holder = [[myCDD objectAtIndex:cddNum] mutableSetValueForKey:@"ncus"];
					[ holder addObject:tempNCU ];
					[[myCDD objectAtIndex:cddNum] setValue:holder forKey:@"ncus"];
					
					holder = [tempNCU mutableSetValueForKey:@"cdds"];
					[holder addObject:[myCDD objectAtIndex:cddNum]];
					[tempNCU setValue:holder forKey:@"cdds"];
					
					[tempNCU setValue:[NSNumber numberWithInt:[[tempNCU valueForKey:@"cddCount"] intValue] +1] forKey:@"cddCount"];
					
					cddNum++;
					if (cddNum == [myCDD count])
					{
						finCDD = 1;
						break;
					}
				}
				
			}
		}
		if ( finUCE == 0 ){
			
			
			if ( [[[myUCE objectAtIndex:uceNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])
			{
				while ([[[myUCE objectAtIndex:uceNum] valueForKey:@"ncuID"] isEqualToString:[tempNCU name]])
				{
					//	NSLog(@"UCEs");
					holder = [[myUCE objectAtIndex:uceNum] mutableSetValueForKey:@"ncus"];
					[holder addObject:tempNCU];
					[[myUCE objectAtIndex:uceNum] setValue:holder forKey:@"ncus"];
					
					holder = [tempNCU mutableSetValueForKey:@"uces"];
					[holder addObject:[myUCE objectAtIndex:uceNum]];
					[tempNCU setValue:holder forKey:@"uces"];
					
					[tempNCU setValue:[NSNumber numberWithInt:[[tempNCU valueForKey:@"uceCount"] intValue] +1] forKey:@"uceCount"];
					
					uceNum++;
					if (uceNum == [myUCE count])
					{
						finUCE = 1;
						break;
					}
				}
			}
		}
		
	}
	NSLog(@" 499");
	id protStartSort = [[NSSortDescriptor alloc] initWithKey:@"protStart" ascending:YES];
	id protStartSortDescriptors = [NSArray arrayWithObject: protStartSort];
	
	
	// Make sure to retrieve the Array Controller's 
	
	// Blocks
	
	// UCE
	// CDD
	// Blocks
	int ii;
	for (ii=0; ii<[myNCU count]; ii++)
	{
		NSLog(@" 514 loop");
		id tempNCU = [myNCU objectAtIndex:ii];
		NSLog(@"%@",[tempNCU description]);
		
		id myBlocks = [[[tempNCU mutableSetValueForKey:@"blocks"] allObjects]sortedArrayUsingDescriptors:blocksSortDescriptors];
		// UCE
		id myUCE = [[[tempNCU mutableSetValueForKey:@"cdds"] allObjects]sortedArrayUsingDescriptors:cddSortDescriptors];
		// CDD
		id myCDD = [[[tempNCU mutableSetValueForKey:@"uces"] allObjects]sortedArrayUsingDescriptors:uceSortDescriptors];
		
		id myCluster = [NSEntityDescription insertNewObjectForEntityForName:@"Cluster" inManagedObjectContext:managedObjectContext];
		
		id temp = [myCluster mutableSetValueForKey:@"ncus"];
		[temp addObject:tempNCU];
		[myCluster setValue:temp forKey:@"ncus"];
		[myCluster setValue:[NSNumber numberWithInt:1] forKey:@"id"];
		temp = [tempNCU mutableSetValueForKey:@"cluster"];
		[temp addObject:myCluster];
		[tempNCU setValue:temp forKey:@"cluster"];
		
		NSLog(@"%@%@%@",[myCDD description],[myBlocks description],[myUCE description]);
		id sortArray = [[NSMutableArray alloc] init];
		if ([myBlocks count]!=0)
		{
			[sortArray addObjectsFromArray:myBlocks];
		}
		if ([myCDD count]!=0)
		{
			[sortArray addObjectsFromArray:myCDD];
		}
		if ([myUCE count]!=0)
		{
			[sortArray addObjectsFromArray:myUCE];
		}
		
		if ([sortArray count] > 0)
		{
			
			NSLog(@"%@",[sortArray sortedArrayUsingDescriptors:protStartSortDescriptors]);
			
			id Y;
			id X = [sortArray objectAtIndex:0];
			[myCluster setValue:[X valueForKey:@"protStart"] forKey:@"protStart"];
			if ([[X entity] isKindOfEntity:blocksEntity])
			{
				temp = [myCluster mutableSetValueForKey:@"blocks"];
				[temp addObject:X];
				[myCluster setValue:temp forKey:@"blocks"];
				
				temp = [X mutableSetValueForKey:@"cluster"];
				[temp addObject:myCluster];
				[X setValue:temp forKey:@"cluster"];
			}
			if ([[X entity] isKindOfEntity:uceEntity])
			{	
				temp = [myCluster mutableSetValueForKey:@"uces"];
				[temp addObject:X];
				[myCluster setValue:temp forKey:@"uces"];
				
				temp = [X mutableSetValueForKey:@"cluster"];
				[temp addObject:myCluster];
				[X setValue:temp forKey:@"cluster"];
			}
			if ([[X entity] isKindOfEntity:cddEntity])
			{	
				temp = [myCluster mutableSetValueForKey:@"cdds"];
				[temp addObject:X];
				[myCluster setValue:temp forKey:@"cdds"];
				
				temp = [X mutableSetValueForKey:@"cluster"];
				[temp addObject:myCluster];
				[X setValue:temp forKey:@"cluster"];
			}
			for (i=1; i< [sortArray count]; i++)
			{
				
				Y = [sortArray objectAtIndex:i];
				if ([[X valueForKey:@"protEnd"] intValue] > [[Y valueForKey:@"protStart"] intValue])
				{
					NSLog(@"Adding X %i > Y %i ", [[X valueForKey:@"protEnd"] intValue], [[Y valueForKey:@"protStart"] intValue]	);
					
					if ([[Y entity] isKindOfEntity:blocksEntity])
					{
						temp = [myCluster mutableSetValueForKey:@"blocks"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"blocks"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];
					}
					if ([[Y entity] isKindOfEntity:uceEntity])
					{	
						temp = [myCluster mutableSetValueForKey:@"uces"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"uces"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];
					}
					if ([[Y entity] isKindOfEntity:cddEntity])
					{	
						temp = [myCluster mutableSetValueForKey:@"cdds"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"cdds"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];
					}
				}
				else
				{
					NSLog(@"Did Not Add X %i < Y %i ", [[X valueForKey:@"protEnd"] intValue], [[Y valueForKey:@"protStart"] intValue]	);
					[myCluster setValue:[X valueForKey:@"protEnd"] forKey:@"protEnd"];
					// NSLog(@"myCluster = %@",[myCluster description]);
					int jj = [[myCluster valueForKey:@"id"] intValue];
					myCluster = [NSEntityDescription insertNewObjectForEntityForName:@"Cluster" inManagedObjectContext:managedObjectContext];
					temp = [myCluster mutableSetValueForKey:@"ncus"];
					[temp addObject:tempNCU];
					[myCluster setValue:temp forKey:@"ncus"];
					[myCluster setValue:[X valueForKey:@"protStart"] forKey:@"protStart"];
					[myCluster setValue:[NSNumber numberWithInt:++jj] forKey:@"id"];
					
					temp = [tempNCU mutableSetValueForKey:@"cluster"];
					[temp addObject:myCluster];
					[tempNCU setValue:temp forKey:@"cluster"];
					
					if ([[Y entity] isKindOfEntity:blocksEntity])
					{
						blocksNum++;
						temp = [myCluster mutableSetValueForKey:@"blocks"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"blocks"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];
					}
					if ([[Y entity] isKindOfEntity:uceEntity])
					{	
						uceNum++;
						temp = [myCluster mutableSetValueForKey:@"uces"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"uces"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];
					}
					if ([[Y entity] isKindOfEntity:cddEntity])
					{	
						cddNum++;	
						temp = [myCluster mutableSetValueForKey:@"cdds"];
						[temp addObject:Y];
						[myCluster setValue:temp forKey:@"cdds"];
						
						temp = [Y mutableSetValueForKey:@"cluster"];
						[temp addObject:myCluster];
						[Y setValue:temp forKey:@"cluster"];				
					}
				}
				NSLog(@"myCluster = %@",[myCluster description]);
				X = Y;
			}
			[myCluster setValue:[X valueForKey:@"protEnd"] forKey:@"protEnd"];
		}
	}
	
	NSLog(@"%@",[myNCU description]);
	[myIndicator stopAnimation:self];
	[mySystemMessages setStringValue:@"Finished! What's Next?"];
	
	
}



/**
 Implementation of the applicationShouldTerminate: method, used here to
 handle the saving of changes in the application managed object context
 before the application terminates.
 */

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
	
    NSError *error;
    int reply = NSTerminateNow;
    
    if (managedObjectContext != nil) {
        if ([managedObjectContext commitEditing]) {
            if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
				
                // This error handling simply presents error information in a panel with an 
                // "Ok" button, which does not include any attempt at error recovery (meaning, 
                // attempting to fix the error.)  As a result, this implementation will 
                // present the information to the user and then follow up with a panel asking 
                // if the user wishes to "Quit Anyway", without saving the changes.
				
                // Typically, this process should be altered to include application-specific 
                // recovery steps.  
				
                BOOL errorResult = [[NSApplication sharedApplication] presentError:error];
				
                if (errorResult == YES) {
                    reply = NSTerminateCancel;
                } 
				
                else {
					
                    int alertReturn = NSRunAlertPanel(nil, @"Could not save changes while quitting. Quit anyway?" , @"Quit anyway", @"Cancel", nil);
                    if (alertReturn == NSAlertAlternateReturn) {
                        reply = NSTerminateCancel;	
                    }
                }
            }
        } 
        
        else {
            reply = NSTerminateCancel;
        }
    }
    
    return reply;
}


/**
 Implementation of dealloc, to release the retained variables.
 */

- (void) dealloc {
	
    [managedObjectContext release], managedObjectContext = nil;
    [persistentStoreCoordinator release], persistentStoreCoordinator = nil;
    [managedObjectModel release], managedObjectModel = nil;
    [super dealloc];
}


@end
